package com.lzh.farmersshop.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.lzh.farmersshop.config.AlipayConfig;
import com.lzh.farmersshop.entity.Order;
import com.lzh.farmersshop.entity.Userinfo;
import com.lzh.farmersshop.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Controller
@RequestMapping("mall/alipay")
@Transactional(rollbackFor = Exception.class)
public class AliPayController {

    @Resource
    private OrderService orderService;

    @GetMapping("/pay")
    public void pay(Order order, HttpServletResponse httpResponse) throws Exception {
        //根据订单id查询数据
        Order order1 = orderService.getById(order.getId());
        //修改订单状态为代付款
        order1.setState(1);
        orderService.updateById(order1);

        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
        AlipayTradePagePayRequest alipay_request = new AlipayTradePagePayRequest();
        alipay_request.setNotifyUrl(AlipayConfig.NOTIFY_URL);
        alipay_request.setReturnUrl(AlipayConfig.RETURN_URL);

        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(order1.getOrderid().toString());
        model.setTotalAmount(order1.getSumprice().toString());
        model.setSubject("农资商贸");
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        alipay_request.setBizModel(model);

        String formHtml = alipayClient.pageExecute(alipay_request).getBody();
        log.info(formHtml);
        httpResponse.setContentType("text/html;charset=utf-8");
        // 直接将完整的表单html输出到页面
        httpResponse.getWriter().write(formHtml);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    @PostMapping("/notifyUrl")
    public ModelAndView notifyUrl(HttpServletRequest request) throws AlipayApiException {
        ModelAndView mv = new ModelAndView("mall/payResult");
        // 获取支付宝返回的所有参数
        // 1.从支付宝回调的request域中取值放到map中
        Map<String, String[]> requestParams = request.getParameterMap();

        Map<String, String> params = new HashMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        log.info("notifyUrl支付宝返回的参数：" + params);
        // 验证签名（确保这个请求是支付宝发出的）
        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);

        if (signVerified) {
            // 签名验证通过
            String outTradeNo = request.getParameter("out_trade_no"); // 获取订单号
            String tradeStatus = request.getParameter("trade_status"); // 获取交易状态

            //WAIT_BUYER_PAY：交易创建，等待买家付款。
            //TRADE_CLOSED：在指定时间段内未支付时关闭的交易或在交易完成全额退款成功时关闭的交易。
            //TRADE_SUCCESS：商家签约的产品支持退款功能的前提下，买家付款成功。
            //TRADE_FINISHED：商家签约的产品不支持退款功能的前提下，买家付款成功。或者，商家签约的产品支持退款功能的前提下，交易已经成功并且已经超过可退款期限。

            // 根据交易状态向用户展示相应的页面或信息
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                // 支付成功，向用户展示成功页面
                mv.addObject("message", "支付成功！");

                // 根据订单号更新订单状态为已支付
                UpdateWrapper<Order> orderWrapper = new UpdateWrapper<>();
                orderWrapper.eq("orderid", outTradeNo);
                orderWrapper.set("state", 2);
                orderService.update(orderWrapper);
            } else {
                // 支付失败或取消，向用户展示失败页面
                mv.addObject("message", "支付失败或取消！");
            }
            // 返回支付成功的视图或数据
            return mv;
        } else {
            // 签名验证失败
            // 返回错误信息或视图
            mv.addObject("message", "签名验证失败支付失败或取消！");
            return mv;
        }
    }


    @GetMapping("/returnUrl")
    public ModelAndView returnUrl(HttpServletRequest request) {
        ModelAndView mv = new ModelAndView("mall/payResult");
        if (request.getSession().getAttribute("userinfo") == null) {
            //如果为空说明用户没有登录，必须登录后之后才能看购物车
            mv.addObject("userinfo", new Userinfo());
            return new ModelAndView("redirect:/mall/login");
        }else{
            mv.addObject("userinfo", request.getSession().getAttribute("userinfo"));
        }
        Userinfo userinfo = (Userinfo) request.getSession().getAttribute("userinfo");
        Date birthday = userinfo.getBirthday();
        if (birthday == null) {
            mv.addObject("birthday", "");
        } else {
            // 转换为 LocalDateTime 类型
            LocalDateTime localDateTime = new java.sql.Timestamp(
                    birthday.getTime()).toLocalDateTime();

            // 创建 DateTimeFormatter 对象并设定转换格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

            // 格式化日期
            String formattedDate = localDateTime.format(formatter);
            mv.addObject("birthday", formattedDate);
        }
        // 1.从支付宝回调的request域中取值放到map中
        Map<String, String[]> requestParams = request.getParameterMap();

        Map<String, String> params = new HashMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        log.info("returnUrl支付宝返回的参数：" +params);
        // 根据订单号更新订单状态为已支付
        UpdateWrapper<Order> orderWrapper = new UpdateWrapper<>();
        orderWrapper.eq("orderid", params.get("out_trade_no"));
        orderWrapper.set("state", 2);
        orderService.update(orderWrapper);
        mv.addObject("message", "支付成功！");
       return mv;
    }


}
